package com.ipartek.formacion.migracion;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.SQLException;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import com.ipartek.formacion.DAO.MySqlDAOFactory;
import com.ipartek.formacion.DAO.MySqlPersonaDAO;
import com.ipartek.formacion.beans.Persona;
import com.ipartek.formacion.enumeraciones.Rol;
import com.ipartek.formacion.excepciones.PersonaException;

/**
 * Clase principal que realiza la migracion de un fichero de texto plano de
 * personas a BBDD
 * 
 * @author Curso
 * 
 */
public class migracionXX {

	// Variables log
	// Variable para trabajar con la logger
	private static final Logger log = Logger.getLogger(MySqlPersonaDAO.class);
	// Variable para trabajar el archivo log4j.properties
	private static final String LOG4J_PROPERTIES = "config/log4j.properties";

	// Fichero con las personas a migrar a BBDD
	static final String PATH_FICHERO_PERSONAS = "data/personas.txt";

	// Variables para la lectura del fichero de personas a migrar a BBDD
	private static File fPersonas = null;
	private static BufferedReader brPersonas = null;

	public static void main(String[] args) throws Exception {

		long tiempo = System.currentTimeMillis();

		// contadores para los registros insertados y erroneos
		int correctos = 0;
		int erroneos = 0;
		// Propiedades para el loj
		PropertyConfigurator.configure(LOG4J_PROPERTIES);

		// Creo la factoria para poder trabajar con la BBDD
		MySqlPersonaDAO personaDAO = null;
		MySqlDAOFactory factoria = new MySqlDAOFactory();

		// Obtengo el DAO de la tabla personas
		try {
			personaDAO = factoria.getInterfacePersonaDAO();
		} catch (Exception e) {
			log.fatal("Error al crear la interface de PersonaDAO "
					+ e.getMessage());
			throw new Exception();
		}

		// Fichero con las personas a migrar a BBDD
		fPersonas = new File(PATH_FICHERO_PERSONAS);

		try {
			// Buffer de lectura del fichero de personas a migrar a BBDD
			brPersonas = new BufferedReader(new FileReader(fPersonas));
		} catch (FileNotFoundException e) {
			log.fatal("Fichero de personas no encontrado " + e.getMessage());
		} catch (Exception e) {
			log.fatal("Excepcion general en la apertura del fichero de personas "
					+ e.getMessage());
		}

		log.info("INICIO TRATAMIENTO FICHERO PERSONAS");
		log.info("===================================");

		// Variable para la lectura de cada personas del fichero
		String lineaPersona = null;

		// Bucle para la lectura del fichero de personas
		for (;;) {

			// Leo una persona del fichero de personas
			try {
				lineaPersona = brPersonas.readLine();
			} catch (IOException e) {
				log.fatal("Excepcion IO leyendo fichero de personas"
						+ e.getMessage());
				break;
			} catch (Exception e) {
				log.fatal("Excepcion general leyendo fichero de personas"
						+ e.getMessage());
				break;
			}

			// Si no hay mas lineas que leer del fichero, salgo del bucle de
			// lectura
			if (lineaPersona == null) {
				break;
			}

			// Separo sus datos por ',' y los guardo en un array
			String[] datosPersona = lineaPersona.split(",");

			if (datosPersona.length != 7) {
				log.error("La persona "
						+ lineaPersona
						+ " no tiene todos los datos necesarios. No se migra a BBDD.");
				erroneos++;
				continue;
			}

			// recupero cada dato del array de la persona
			String nombre = datosPersona[0];
			String apellido1 = datosPersona[1];
			String apellido2 = datosPersona[2];
			String edadPersona = datosPersona[3];
			String email = datosPersona[4];
			String dni = datosPersona[5];
			String rolPersona = datosPersona[6];

			Rol rol = Rol.valueOf(rolPersona.toUpperCase());

			// Compruebo que el rol es unos de los 3 definidos
			if (!rol.equals(Rol.CLIENTE) && rol.equals(Rol.JEFE)
					&& rol.equals(Rol.TRABAJADOR)) {
				log.error("La persona " + lineaPersona
						+ " tiene un rol erroneo. No se migra a BBDD.");
				erroneos++;
				continue;
			}

			// Compruebo que la edad es numerica
			int edad = 0;

			try {
				edad = Integer.parseInt(edadPersona);
			} catch (NumberFormatException e) {
				log.error("La persona " + lineaPersona
						+ " tiene la edad erronea. No se migra a BBDD.");
				erroneos++;
				continue;
			}

			// Creo el objeto persona con los datos obtenidos del fichero
			Persona persona = null;
			try {
				persona = new Persona(nombre, apellido1, apellido2, edad, dni,
						email, rol);
			} catch (PersonaException e) {
				log.error(e.getMensajeError() + " " + lineaPersona);
				erroneos++;
				continue;
			} catch (Exception e) {
				log.error("Se a producido un error al crear el objeto persona "
						+ lineaPersona);
				erroneos++;
				continue;
			}

			// Inserto el objeto persona en la BBDD
			try {
				personaDAO.insertPersona(persona);
			} catch (SQLException e) {
				log.error("No se ha insertado la persona " + lineaPersona);
				erroneos++;
				continue;
			} catch (Exception e) {
				log.error("No se ha insertado la persona " + lineaPersona);
				erroneos++;
				continue;
			}
			correctos++;
		}

		tiempo = System.currentTimeMillis() - tiempo;
		log.info("================================");
		log.info("FIN TRATAMIENTO FICHERO PERSONAS");
		log.info("================================");
		log.info("Tiempo de ejecucion " + tiempo);
		log.info("Correctos ---->            " + correctos);
		log.info("Erroneos ---->             " + erroneos);
		log.info("================================");

		try {
			// Realizo el commit de todas las INSERT
			if (personaDAO != null) {
				log.info("COMMIT BBDD");
				personaDAO.commit();
			} else {
				log.info("No se realiza COMMIT BBDD, por conexion nula.");
			}
		} catch (Exception e) {
			// Si hay excepcion, hago rollback
			log.fatal("Error al hacer COMMIT " + e.getMessage());
			personaDAO.rollback();
			log.info("Se realiza ROLLBACK.");
		}

		System.out.println("PROCESO FINALIZADO");
	}
}